/*
@file	CustomRectangle.cpp
@author	Saume
*/

#include "CustomRectangle.h"
#include "Circle.h"
#include "LineSegment.h"

CustomRectangle::CustomRectangle(): 
Polygon() {
	width = 0.0f;
	height = 0.0f;
}

CustomRectangle::CustomRectangle(float xVal, float yVal, float wVal, float hVal): 
Polygon(xVal, yVal) {
	width = (wVal < 0) ? -wVal : wVal;
	height = (hVal < 0) ? -hVal : hVal;
}

CustomRectangle::CustomRectangle(const Vector* const v1, const Vector* const v2): 
Polygon() {
	if (v1->x > v2->x) {
		x = v2->x;
		width = v1->x - x;
	} else {
		x = v1->x;
		width = v2->x - x;
	}

	if (v1->y > v2->y) {
		y = v2->y;
		height = v1->y - y;
	} else {
		y = v1->y;
		height = v2->y - y;
	}
}

/*
Returns the width of the rectangle.
*/
float CustomRectangle::GetWidth() const {
	return width;
}

/*
Returns the height of the rectangle.
*/
float CustomRectangle::GetHeight() const {
	return height;
}

/*
Returns wether or not the given point is inside the bounds of the rectangle.
*/
bool CustomRectangle::Contains(float xVal, float yVal) const {
	if (xVal >= x && xVal <= x + width) { // is within x range of the rectangle
		if (yVal >= y && yVal <= y + height) { // is within y range of the rectangle
			return true;
		}
	}
	return false;
}

/*
Returns wether or not the given point vector is inside the bounds of the rectangle.
Does not consider the Z axis.
*/
bool CustomRectangle::Contains(const Vector* const v) const {
	return Contains(v->x, v->y);
}

/*
Determines wether the rectangle is colliding with the given rectangle or not.
*/
bool CustomRectangle::CollidesWith(const CustomRectangle* const r) const {
	if (x <= r->x + r->width) { // left <= r->right
		if (x + width >= r->x) { // right >= r->left
			if (y <= r->y + r->height) { // (top / bottom) <= (r->bottom / r->top)
				if (y + height >= r->y) { // (bottom / top) >= (r->top / r->bottom)
					return true;
				}
			}
		}
	}
	return false;
}

/*
Determines wether the rectangle is colliding with the given circle or not.
*/
bool CustomRectangle::CollidesWith(const Circle* const c) const {
	return c->CollidesWith(this);
}

/*
Displays the opposite corners of the rectangle, so the origin coordinate and its end.
*/
void CustomRectangle::Display() const {
	std::cout << "(" << x << ", " << y << "), (" << x + width << ", " << y + height << ")";
	return;
}

/*
Determines wether two rectangles have the same position and size or not.
*/
bool operator==(const CustomRectangle& r1, const CustomRectangle& r2) {
	float dx = r2.GetX() - r1.GetX();
	float dy = r2.GetY() - r1.GetY();
	float dw = r2.GetWidth() - r1.GetWidth();
	float dh = r2.GetHeight() - r1.GetHeight();
	dx = fabs(dx);
	dy = fabs(dy);
	dw = fabs(dw);
	dh = fabs(dh);
	
	return dx <= EPSILON_DBL && dy <= EPSILON_DBL && dw <= EPSILON_DBL && dh <= EPSILON_DBL;
}